
#include "c_ClientTCP_Socket.h"
#include <assert.h>

/**
 * Makes a connection to the speicied server & port
 *
 * @param  ServerAddress Server IP address
 * @param  ServerPort    Port of server
 * @retval e_Status      
 */   
wiigi::e_Status wiigi::c_ClientTCP_Socket::connectToServer( const c_IPv4_Address& ServerAddress, u16 ServerPort )
{
   assert( checkFlags( d_Connected ) == 0 ); //Should not already be connected
   assert( ServerAddress.checkValid() );
   assert( INVALID_SOCKET != m_Socket );
   
   e_Status Status;
   Status = d_StatusUnkown;
   
   if( INVALID_SOCKET == m_Socket )
   {
      Status = d_IllegalRequest;
      goto Exit;
   }
      
   if( checkFlags( d_Connected ) )
   {
      Status = d_SocketAlreadyConnected;
      goto Exit;
   }
   
   if( ServerAddress.checkValid() == false )
   {
      Status = d_BadAdress;
      goto Exit;
   }
   
   memset( &m_Address, 0, sizeof( m_Address ) );
   
   m_Address.sin_addr.s_addr = ServerAddress.getIntegerAddress();
   m_Address.sin_port        = ServerPort;
   m_Address.sin_family      = AF_INET; 
   
   s32 RetValue;
   RetValue = net_connect(m_Socket,(struct sockaddr*)&m_Address,sizeof( m_Address ) );
   if( RetValue < 0 )
   {
      Status = d_IllegalRequest;
      goto Exit;
   }
      
   int OpValue;
   OpValue = 1;          //@todo - try and understand what this means...
   net_setsockopt(m_Socket,IPPROTO_TCP,TCP_NODELAY,&OpValue,sizeof(OpValue)); //@Do we need to do this? Can it fail?
   
   setFlag( d_Connected );
   Status = d_StatusOK;

Exit:   
   assert( d_StatusUnkown != Status );
   return Status;
}

/**
 * Sends the specified buffer to server
 * 
 * @param Buffer     Address to src data from
 * @param BufferSize How many bytes to send
 * @retval e_Status
 */  
wiigi::e_Status wiigi::c_ClientTCP_Socket::sendBuffer( const void* Buffer, u32 BufferSize )
{
   assert( checkFlags( d_Connected )  );
   assert( INVALID_SOCKET != m_Socket );
   assert( 0 != Buffer );
   assert( 0 < BufferSize );
   
   e_Status Status;
   Status = d_StatusUnkown;
   
   if( checkFlags( d_Connected ) == false )
   {
      Status = d_SocketNotConnected;
      goto Exit;
   }
   
   if( INVALID_SOCKET == m_Socket )
   {
      Status = d_IllegalRequest;
      goto Exit;
   }
   
   if( Buffer     == 0 || 
       BufferSize == 0    )
   {
      Status = d_BadParameters;
      goto Exit;
   }
   
   s32 RetVal;
   RetVal = net_write(m_Socket, Buffer, BufferSize );
   if( RetVal < 0 )
   {
      Status = d_IllegalRequest;
   }
   else
   {
      Status = d_StatusOK;
   }   
      
Exit:   
   assert( d_StatusUnkown != Status );
   return Status;
}
